package cn.lili.modules.promotion.serviceimpl;

import cn.lili.modules.member.entity.dos.User;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.extra.cglib.CglibUtil;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.ResultUtil;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.ResultMessage;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
import cn.lili.modules.goods.entity.enums.GoodsTypeEnum;
import cn.lili.modules.member.client.UserClient;
import cn.lili.modules.promotion.entity.dos.BoxMhgoods;
import cn.lili.modules.promotion.entity.dto.search.BoxSearchParams;
import cn.lili.modules.promotion.entity.vos.BoxLotteryTicketVO;
import cn.lili.modules.promotion.entity.vos.BoxMhgoodsVO;
import cn.lili.modules.promotion.entity.vos.LotteryVO;
import cn.lili.modules.promotion.service.BoxMhgoodsService;
import cn.lili.modules.system.client.DictionaryClient;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.constants.DictConstant;
import cn.lili.modules.system.entity.dos.Dictionary;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.lili.modules.promotion.entity.dos.BoxLotteryTicket;
import cn.lili.modules.promotion.service.BoxLotteryTicketService;
import cn.lili.modules.promotion.mapper.BoxLotteryTicketMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
* @author asus
* @description 针对表【li_box_lottery_ticket】的数据库操作Service实现
* @createDate 2023-11-22 17:32:13
*/
@Service
@Slf4j
public class BoxLotteryTicketServiceImpl extends ServiceImpl<BoxLotteryTicketMapper, BoxLotteryTicket>
    implements BoxLotteryTicketService{

    @Resource
    private DictionaryClient dictionaryClient;

    @Resource
    @Lazy
    private BoxMhgoodsService boxMhgoodsService;

    @Resource
    private GoodsClient goodsClient;
    @Resource
    private UserClient userClient;

    @Override
    public ResultMessage<Object> pageBox(BoxSearchParams params) {
        Page<BoxLotteryTicket> mhgoodsPage = super.page(PageUtil.initPage(params), this.createLambdaQueryWrapper(params));
        return ResultUtil.data(this.conversion(mhgoodsPage));
    }

    private Page<BoxLotteryTicketVO> conversion(Page<BoxLotteryTicket> paramsPage) {
        //复制page对象
        if (CollectionUtil.isEmpty(paramsPage.getRecords())) {
            return new Page<BoxLotteryTicketVO>();
        }
        long beginTime = System.currentTimeMillis();
        Page<BoxLotteryTicketVO> resultPage = new Page<>();
        BeanUtils.copyProperties(paramsPage, resultPage);
        List<BoxLotteryTicket> records = paramsPage.getRecords();
        List<BoxLotteryTicketVO> voList = CglibUtil.copyList(records, BoxLotteryTicketVO::new);
        resultPage.setRecords(voList);
        System.out.println("System.currentTimeMillis() = " + (System.currentTimeMillis() - beginTime));

        //字典转换
        System.out.println("System.currentTimeMillis() = " + (System.currentTimeMillis() - beginTime));
        List<Dictionary> lotteryTicketStatusList = dictionaryClient.getListByCode(DictConstant.LOTTERY_TICKET_STATUS_NAME);
        System.out.println("System.currentTimeMillis() = " + (System.currentTimeMillis() - beginTime));
        List<Dictionary> activeStateList = dictionaryClient.getListByCode(DictConstant.ACTIVE_STATE_NAME);
        System.out.println("System.currentTimeMillis() = " + (System.currentTimeMillis() - beginTime));

        for (BoxLotteryTicketVO boxLotteryTicketVO : resultPage.getRecords()) {
            if (CollectionUtil.isNotEmpty(lotteryTicketStatusList)) {
                for (Dictionary dictionary : lotteryTicketStatusList) {
                    if (dictionary.getValue().equals(String.valueOf(boxLotteryTicketVO.getLotteryTicketStatus()))) {
                        boxLotteryTicketVO.setLotteryTicketStatusName(dictionary.getValueName());
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(activeStateList)) {
                for (Dictionary dictionary : activeStateList) {
                    if (dictionary.getValue().equals(String.valueOf(boxLotteryTicketVO.getActiveState()))) {
                        boxLotteryTicketVO.setActiveStateName(dictionary.getValueName());
                    }
                }
            }
        }

        return resultPage;
    }


    @Override
    public ResultMessage<Object> addBoxGoods(BoxLotteryTicketVO boxLotteryTicketVO) {

        return ResultUtil.data(super.save(boxLotteryTicketVO));
    }

    @Override
    public ResultMessage<Object> updateBoxGoods(BoxLotteryTicketVO boxLotteryTicketVO) {

        return ResultUtil.data(super.updateById(boxLotteryTicketVO));
    }

    /**
     * 作废
     * @param lotteryTicketId ID
     */
    @Override
    public void cancellation(String lotteryTicketId, String remark) {
        log.info("lotteryTicketId = {} ", lotteryTicketId);
        BoxLotteryTicket boxLotteryTicket = new BoxLotteryTicket();
        boxLotteryTicket.setId(String.valueOf(lotteryTicketId));
        boxLotteryTicket.setLotteryTicketStatus(DictConstant.LOTTERY_TICKET_STATUS_03);
        boxLotteryTicket.setRemark(remark);
        super.updateById(boxLotteryTicket);
    }

    /**
     * 恢复
     * @param lotteryTicketId id
     */
    @Override
    public void recover(String lotteryTicketId) {
        log.info("lotteryTicketId = {} ", lotteryTicketId);
        BoxLotteryTicket boxLotteryTicket = new BoxLotteryTicket();
        boxLotteryTicket.setId(lotteryTicketId);
        boxLotteryTicket.setLotteryTicketStatus(DictConstant.LOTTERY_TICKET_STATUS_01);
        super.updateById(boxLotteryTicket);
    }

    private LambdaQueryWrapper<BoxLotteryTicket> createLambdaQueryWrapper(BoxSearchParams params) {
        LambdaQueryWrapper<BoxLotteryTicket> boxLotteryTicketLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(params.getUserId())) {
            boxLotteryTicketLambdaQueryWrapper.eq(BoxLotteryTicket::getUserId, params.getUserId());
        }
        if (StringUtils.isNotEmpty(params.getUsername())) {
            boxLotteryTicketLambdaQueryWrapper.like(BoxLotteryTicket::getUserName, params.getUsername());
        }
        if (StringUtils.isNotEmpty(params.getMhName())) {
            boxLotteryTicketLambdaQueryWrapper.like(BoxLotteryTicket::getMhName, params.getMhName());
        }
        if (StringUtils.isNotEmpty(params.getLotteryTicketStatus())) {
            boxLotteryTicketLambdaQueryWrapper.eq(BoxLotteryTicket::getLotteryTicketStatus, params.getLotteryTicketStatus());
        }
        if (StringUtils.isNotEmpty(params.getLotteryTicketNo())) {
            boxLotteryTicketLambdaQueryWrapper.eq(BoxLotteryTicket::getLotteryTicketNo, params.getLotteryTicketNo());
        }
        if (StringUtils.isNotEmpty(params.getOrderSn())) {
            boxLotteryTicketLambdaQueryWrapper.like(BoxLotteryTicket::getOrderSn, params.getOrderSn());
        }
        if (params.getActiveState() != null) {
            boxLotteryTicketLambdaQueryWrapper.eq(BoxLotteryTicket::getActiveState, params.getActiveState());
        }
        if (params.getStartCreateTime() != null) {
            boxLotteryTicketLambdaQueryWrapper.ge(BoxLotteryTicket::getCreateTime, params.getStartCreateTime());
        }
        if (params.getEndCreateTime() != null) {
            boxLotteryTicketLambdaQueryWrapper.le(BoxLotteryTicket::getCreateTime, params.getEndCreateTime());
        }
        boxLotteryTicketLambdaQueryWrapper.eq(BoxLotteryTicket::getDeleteFlag, Boolean.FALSE);
        boxLotteryTicketLambdaQueryWrapper.orderByDesc(BoxLotteryTicket::getCreateTime);
        return boxLotteryTicketLambdaQueryWrapper;
    }

    /**
     * 我的奖券
     * @param mhId 盲盒id
     * @return 奖券列表
     */
    @Override
    public ResultMessage<Object> lottery(String mhId) {
        String currentId = UserContext.getCurrentId();
        if (StringUtils.isEmpty(currentId)) {
            throw new ServiceException("登陆已过期，请重新登陆");
        }
        LambdaQueryWrapper<BoxLotteryTicket> ticketLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ticketLambdaQueryWrapper.eq(BoxLotteryTicket::getMhId, mhId);
        ticketLambdaQueryWrapper.in(BoxLotteryTicket::getLotteryTicketStatus, DictConstant.LOTTERY_TICKET_STATUS_01, DictConstant.LOTTERY_TICKET_STATUS_02);
        ticketLambdaQueryWrapper.eq(BoxLotteryTicket::getUserId, currentId);
        ticketLambdaQueryWrapper.orderByDesc(BoxLotteryTicket::getLotteryTicketStatus);
        List<BoxLotteryTicket> ticketList = super.list(ticketLambdaQueryWrapper);
        return ResultUtil.data(this.lotteryConversion(ticketList, mhId));
    }

    private LotteryVO lotteryConversion(List<BoxLotteryTicket> ticketList, String mhId) {
//        if (CollectionUtil.isEmpty(ticketList)) {
//            return new LotteryVO();
//        }
        LotteryVO result = new LotteryVO();
        //计算中奖进度
        LambdaQueryWrapper<BoxLotteryTicket> ticketLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ticketLambdaQueryWrapper.eq(BoxLotteryTicket::getMhId, mhId);
        ticketLambdaQueryWrapper.in(BoxLotteryTicket::getLotteryTicketStatus, DictConstant.LOTTERY_TICKET_STATUS_01, DictConstant.LOTTERY_TICKET_STATUS_02);
        ticketLambdaQueryWrapper.orderByDesc(BoxLotteryTicket::getLotteryTicketStatus);
        long lotteryCount = super.count(ticketLambdaQueryWrapper);
        BoxMhgoods boxMhgoods = boxMhgoodsService.getById(mhId);
        Integer conditions = boxMhgoods.getLotteryConditions();
        int schedule = (int) (((double) lotteryCount / conditions) * 100);
        //由于会连抽，会超卖所以，可能会大于100
        if (schedule > 100) {
            schedule = 100;
        }

        result.setLotteryList(ticketList != null? ticketList : new ArrayList<>());
        result.setSchedule(schedule);
        result.setRaffleTicketsHaveBeenDrawn((int) lotteryCount);
        int surplusTicket = conditions - Integer.parseInt(String.valueOf(lotteryCount));
        result.setSurplusTicket(surplusTicket <= 0 ? 0 : surplusTicket);
        result.setGoods(goodsClient.getById(boxMhgoods.getBigGoodsId()));
        result.setLotteryTime(boxMhgoods.getLotteryTime());
        User user = userClient.getById(UserContext.getCurrentId());
        result.setNickName(user!=null ? user.getNickName() : null);
        result.setUserImage(user!=null ? user.getFace() : null);
        result.setIsWinning(false);
        if (ticketList != null && !ticketList.isEmpty()) {
            for (BoxLotteryTicket boxLotteryTicket : ticketList) {
                if (DictConstant.LOTTERY_TICKET_STATUS_02.equals(boxLotteryTicket.getLotteryTicketStatus())) {
                    result.setIsWinning(true);
                    break;
                }
            }
        }

        ticketLambdaQueryWrapper.clear();
        ticketLambdaQueryWrapper.eq(BoxLotteryTicket::getMhId, mhId);
        ticketLambdaQueryWrapper.eq(BoxLotteryTicket::getLotteryTicketStatus, DictConstant.LOTTERY_TICKET_STATUS_02);
        ticketLambdaQueryWrapper.last("limit 1");
        BoxLotteryTicket boxLotteryTicket = super.getOne(ticketLambdaQueryWrapper);
        result.setLotteryTicketNo(boxLotteryTicket != null ? boxLotteryTicket.getLotteryTicketNo() : null);
        return result;
    }
}




